/**
 * BOM视图检查
 */
package ext.tianma.part.processors;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import wt.fc.ObjectReference;
import wt.fc.Persistable;
import wt.fc.QueryResult;
import wt.fc.collections.WTCollection;
import wt.part.WTPart;
import wt.part.WTPartConfigSpec;
import wt.part.WTPartHelper;
import wt.part.WTPartMaster;
import wt.part.WTPartStandardConfigSpec;
import wt.part.WTPartSubstituteLink;
import wt.part.WTPartUsageLink;
import wt.util.WTException;
import wt.vc.config.ConfigException;
import wt.vc.config.ConfigSpec;
import wt.vc.config.LatestConfigSpec;
import wt.vc.struct.StructHelper;
import wt.vc.views.View;
import wt.vc.views.ViewHelper;
import wt.vc.views.ViewReference;

import com.ptc.core.components.forms.DefaultObjectFormProcessor;
import com.ptc.core.components.forms.FormProcessingStatus;
import com.ptc.core.components.forms.FormResult;
import com.ptc.core.components.util.FeedbackMessage;
import com.ptc.core.ui.resources.FeedbackType;
import com.ptc.netmarkets.util.beans.NmCommandBean;

import ext.com.core.CoreUtil;

public class CheckBOMViewProcessor extends DefaultObjectFormProcessor{
	private static final String D_VIEW = "Design";

	@Override
	public FormResult doOperation( NmCommandBean nmCommandBean , List list )throws WTException {
		FormResult formresult = new FormResult();
		formresult.setStatus(FormProcessingStatus.SUCCESS);
		
		WTPart finishedGood = (WTPart) nmCommandBean.getElementContext().getTargetOid().getRefObject();;	
		
		if( finishedGood != null ){
				
			String partView = finishedGood.getViewName();
				
			if( partView != null && !partView.trim().isEmpty() && !partView.equals( D_VIEW ) ){
				
				List< WTPartMaster > masterList = new ArrayList<WTPartMaster>();
					
				checkBOMByView( finishedGood , partView , masterList );
				
				throwException( masterList , partView );
					
				formresult.addFeedbackMessage( new  FeedbackMessage(
						FeedbackType.SUCCESS, null, "BOM结构检查完毕！", null, new String[] {} ) );
			}		
		}		
		return formresult;
	}	
	
	/**
	 * 检查BOM的中的零部件是否存在与父件相同视图对象
	 * @param part
	 * @param view
	 * @throws ConfigException
	 * @throws WTException
	 */
	private static void checkBOMByView( WTPart part , String view , List< WTPartMaster > masterList ) throws ConfigException, WTException{
		
		if( part == null || view == null || view.trim().isEmpty() ){
			return;
		}
		//获取零部件第一层父子件使用关系
		List< WTPartUsageLink > usageLinkList = getFirstLevelUsageLink( part );
		if( usageLinkList != null ){
			
			Iterator<WTPartUsageLink> iterator = usageLinkList.iterator();
			
			while( iterator.hasNext() ){
				WTPartUsageLink usageLink = iterator.next();
				
				if( usageLink != null ){
					//判断UsageLink的父子间视图是否为指定视图如果不是则报异常
					checkPartView( usageLink , view , masterList );
					//判断特地替代的Master是否存在指定视图对象如果不存在则报错
					checkSubstituteLinkView( usageLink , view , masterList);
					//递归检查整个BOM
					WTPart sonPart = CoreUtil.getWTPartByMasterAndView( usageLink.getUses() , view );
					
					checkBOMByView( sonPart , view , masterList );
				}
			}		
		}		
	}
	
	/**
	 * 判断特地替代的Master是否存在指定视图对象如果不存在则报错
	 * @param usageLink
	 * @param view
	 * @throws WTException
	 */
	private static void checkSubstituteLinkView( WTPartUsageLink usageLink , String view , List< WTPartMaster > masterList ) throws WTException {
		
		if( usageLink == null || view == null || view.trim().isEmpty() ){
			return;
		}
		
		//返回的是一个特定替代关系集合
		WTCollection wtcol = WTPartHelper.service.getSubstituteLinks( usageLink ) ;
		
		WTPartSubstituteLink wtSubstituteLink = null ;
		
		if( wtcol != null ){
			Iterator iterator = wtcol.iterator();
			
			while( iterator.hasNext() ){
				Object object = iterator.next();
				
				if( object != null && object instanceof ObjectReference ){
					ObjectReference orf = ( ObjectReference )object;
					Object obj = orf.getObject();
					
					if( obj != null && obj instanceof WTPartSubstituteLink ){
						wtSubstituteLink = ( WTPartSubstituteLink )obj;
					}
				}else if( object != null && object instanceof WTPartSubstituteLink ){
					wtSubstituteLink = ( WTPartSubstituteLink ) object ;
				}
				
				if( wtSubstituteLink != null ){
					//获取特定替代的Master
					WTPartMaster subMaster = wtSubstituteLink.getSubstitutes();
					
					WTPart sonPart = CoreUtil.getWTPartByMasterAndView( subMaster , view ); 
					
					if( sonPart == null ){
						masterList.add( subMaster );				
					}else if( !( sonPart.getViewName().trim().equals( view.trim() ) ) ){
						masterList.add( subMaster );
					}
				}
			}
		}		
	}


	/**
	 * 判断UsageLink的父子间视图是否为指定视图如果不是则报异常
	 * @param usageLink
	 * @param view
	 * @throws WTException
	 */
	private static void checkPartView( WTPartUsageLink usageLink, String view , List< WTPartMaster > masterList ) throws WTException {
		
		if( usageLink == null || view == null || view.trim().isEmpty() ){
			return;
		}
		
		WTPart part = usageLink.getUsedBy();
		
		if( part != null ){
			String partView = part.getViewName();
						
			if( partView.trim().equals( view.trim() ) ){
				WTPart sonPart = CoreUtil.getWTPartByMasterAndView( usageLink.getUses() , view );
				
				if( sonPart == null ){
					masterList.add( usageLink.getUses() );				
				}else if( !( sonPart.getViewName().trim().equals( view.trim() ) ) ){
					masterList.add( usageLink.getUses() );	
				}
				
			}else{
				masterList.add( ( WTPartMaster )part.getMaster() );	
			}
		}		
	}


	/**
	 * 获取零部件第一层父子件使用关系
	 * 
	 * @param part
	 * @return
	 * @throws ConfigException
	 * @throws WTException
	 */
	public static List<WTPartUsageLink> getFirstLevelUsageLink(WTPart part) throws ConfigException, WTException {
		List<WTPartUsageLink> subPartUsageLinkList = new ArrayList<WTPartUsageLink>() ;
		
		ConfigSpec latestconfigspec = getConfigSpec(part);
		
		QueryResult qr= StructHelper.service.navigateUsesToIteration(part,WTPartUsageLink.class,false,latestconfigspec);
		
		while(qr != null && qr.hasMoreElements()){
			//每一个element实际是一个persistable数组
			Persistable apersistable[] = ( Persistable[] ) qr.nextElement();  
			
			//数组中第一个对象是usagelink
			WTPartUsageLink partUsageLink= (WTPartUsageLink)apersistable[0];   
			
			if(partUsageLink != null){
				subPartUsageLinkList.add(partUsageLink) ;
			}
		}
		
		return subPartUsageLinkList;
	}

	private static ConfigSpec getConfigSpec(WTPart part) {
		ConfigSpec latestconfigspec = new LatestConfigSpec();
		
		String view = "";
		ViewReference viewRef =part.getView();
		if(viewRef != null){
			view = viewRef.getName();
		}
		try{
			if(view != null && view.length()>0){
				View viewObj= ViewHelper.service.getView(view);
				WTPartConfigSpec config = WTPartHelper.service.findWTPartConfigSpec();
				WTPartStandardConfigSpec standardConfig= config.getStandard();
				
				standardConfig.setView(viewObj);		
				latestconfigspec = standardConfig;
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return latestconfigspec ;
	}
	
	/**
	 * 抛出异常
	 * @param part
	 * @param view
	 * @throws WTException
	 */
	private static void throwException( List< WTPartMaster > list , String view ) throws WTException{
		
		if( list == null || view == null ){
			return;
		}
		
		String number = "";
		
		Iterator< WTPartMaster > iterator = list.iterator();
		
		while( iterator.hasNext() ){
			WTPartMaster master = iterator.next();
			
			if( master != null ){
				String masterNumber = master.getNumber();
				
				if( number.trim().isEmpty() ){
					number = masterNumber;
				}else{
					number = number + "," + masterNumber;
				}
			}
		}		
			
		if( number != null && !number.trim().isEmpty() ){
			throw new WTException( "BOM结构中零部件" + number +"没有"+view+"视图。" );
		}
	}
}
